package com.smaato.xml;

import java.io.ByteArrayInputStream;
import net.rim.device.api.xml.parsers.SAXParser;
import net.rim.device.api.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.helpers.DefaultHandler;

public class SmaatoXMLHandler extends DefaultHandler
{
	private SmaatoXMLResponse iResponse;
	private boolean iDone = true;
	private String iParsingState = null;
	private SmaatoXMLResponse.AdInfo iCurrentAd = null;
	private SmaatoXMLResponse.BeaconInfo iCurrentBeacon = null;
	
	public SmaatoXMLResponse parseXML(byte[] aData)
	{	
		if(iDone == true)
		{
			try
			{
				SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
				parser.setNamespaceAware(true);
				
				ByteArrayInputStream is = new ByteArrayInputStream(aData);
				parser.parse(is, this);
	
				return iResponse;
			}
			catch(Exception e)
			{
				// Something went wrong with the init of the xml parser
				return null;
			}
		}
		else
		{
			return null;
		}
	}
	
	public void startDocument() 
	{
		iDone = false;
		iResponse = new SmaatoXMLResponse();
	}
	
	public void characters(char[] ch, int start, int length) 
	{
		if(iParsingState != null)
		{
			if(iParsingState.equalsIgnoreCase("status"))
			{
				if(iResponse.getSuccess() == null)
				{
					iResponse.setSuccess(new String(ch, start, length));
				}
				else
				{
					iResponse.setSuccess(iResponse.getSuccess() + new String(ch, start, length));
				}
			}
			else if(iParsingState.equalsIgnoreCase("errorCode"))
			{
				if(iResponse.getErrorCode() == null)
				{
					iResponse.setErrorCode(new String(ch, start, length));
				}
				else
				{
					iResponse.setErrorCode(iResponse.getErrorCode() + new String(ch, start, length));
				}
			}
			else if(iParsingState.equalsIgnoreCase("errorDesc"))
			{
				if(iResponse.getErrorString() == null)
				{
					iResponse.setErrorString(new String(ch, start, length));
				}
				else
				{
					iResponse.setErrorString(iResponse.getErrorString() + new String(ch, start, length));
				}
			}
			else if(iParsingState.equalsIgnoreCase("userid"))
			{
				if(iResponse.getUserID() == null)
				{
					iResponse.setUserID(new String(ch, start, length));
				}
				else
				{
					iResponse.setUserID(iResponse.getUserID() + new String(ch, start, length));
				}
			}
			else if(iParsingState.equalsIgnoreCase("link"))
			{
				if(iCurrentAd.getLink() == null)
				{
					iCurrentAd.setLink(new String(ch, start, length));
				}
				else
				{
					iCurrentAd.setLink(iCurrentAd.getLink() + new String(ch, start, length));
				}
			}
			else if(iParsingState.equalsIgnoreCase("adtext"))
			{
				if(iCurrentAd.getAdText() == null)
				{
					iCurrentAd.setAdText(new String(ch, start, length));
				}
				else
				{
					iCurrentAd.setAdText(iCurrentAd.getAdText() + new String(ch, start, length));
				}
			}
			else if(iParsingState.equalsIgnoreCase("beacon"))
			{
				if(iCurrentBeacon.getBeaconUrl() == null)
				{
					iCurrentBeacon.setBeaconUrl(new String(ch, start, length));
				}
				else
				{
					iCurrentBeacon.setBeaconUrl(iCurrentBeacon.getBeaconUrl() + new String(ch, start, length));
				}
			}
		}
	}
	
	public void startElement(String uri, String localName, String qName, Attributes attributes)
	{	
		if(qName.equalsIgnoreCase("status"))
		{
			iParsingState = "status";
		}
		else if(qName.equalsIgnoreCase("code"))
		{
			iParsingState = "errorCode";
		}
		else if(qName.equalsIgnoreCase("desc"))
		{
			iParsingState = "errorDesc";
		}
		else if(qName.equalsIgnoreCase("id"))
		{
			iParsingState = "userid";
		}
		else if(qName.equalsIgnoreCase("ad"))
		{
			iCurrentAd = iResponse.new AdInfo();
			
			int length = attributes.getLength();
			for(int i=0; i < length; i++)
			{
				String name = attributes.getLocalName(i);
				
				if(name.equalsIgnoreCase("id"))
				{
					iCurrentAd.setAdId(attributes.getValue(i));
				}
				else if(name.equalsIgnoreCase("type"))
				{
					iCurrentAd.setAdType(attributes.getValue(i));
				}
				else if(name.equalsIgnoreCase("refresh"))
				{
					iCurrentAd.setRefreshTime(attributes.getValue(i));
				}
				else if(name.equalsIgnoreCase("caching"))
				{
					iCurrentAd.setCaching(attributes.getValue(i));
				}
				else if(name.equalsIgnoreCase("priority"))
				{
					iCurrentAd.setPriority(attributes.getValue(i));
				}
			}
		}
		else if(qName.equalsIgnoreCase("valid"))
		{
			int length = attributes.getLength();
			for(int i=0; i < length; i++)
			{
				String name = attributes.getLocalName(i);
				
				if(name.equalsIgnoreCase("start"))
				{
					iCurrentAd.setValidStart(attributes.getValue(i));
				}
				else if(name.equalsIgnoreCase("end"))
				{
					iCurrentAd.setValidEnd(attributes.getValue(i));
				}
				else if(name.equalsIgnoreCase("max"))
				{
					iCurrentAd.setValidMax(attributes.getValue(i));
				}
			}
		}
		else if(qName.equalsIgnoreCase("link"))
		{
			iParsingState = "link";
		}
		else if(qName.equalsIgnoreCase("action"))
		{
			int length = attributes.getLength();
			for(int i=0; i < length; i++)
			{
				String name = attributes.getLocalName(i);
				
				if(name.equalsIgnoreCase("target"))
				{
					iCurrentAd.setTarget(attributes.getValue(i));
				}
				else if(name.equalsIgnoreCase("type"))
				{
					iCurrentAd.setType(attributes.getValue(i));
				}
			}
		}
		else if(qName.equalsIgnoreCase("adtext"))
		{
			iParsingState = "adtext";
		}
		else if(qName.equalsIgnoreCase("beacon"))
		{
			iCurrentBeacon = iResponse.new BeaconInfo();
			iParsingState = "beacon";
		}
	}
	
	public void endElement(String uri, String localName, String qName) 
	{
		iParsingState = null;
		if(qName.equalsIgnoreCase("ad"))
		{
			iResponse.addAd(iCurrentAd);
			iCurrentAd = null;
		}
		else if(qName.equalsIgnoreCase("beacon"))
		{
			iCurrentAd.addBeacon(iCurrentBeacon);
			iCurrentBeacon = null;
		}
	}
	
	public void endDocument()
	{
		iDone = true;
	}
}
